# pyinstaller -F -w --add-data "config.ini;." getStudent.py
import os
import re
import tkinter as tk
import configparser
from tkinter import filedialog, messagebox

class HomeworkManager:
    def __init__(self):
        self.window = tk.Tk()
        self.window.title("作业收集管理系统")
        self.config_file = "config.ini"
        
        # 创建界面组件
        self.create_widgets()
        # 加载配置文件
        self.load_config()

    def create_widgets(self):
        """创建图形界面"""
        # 学生名单路径
        tk.Label(self.window, text="学生名单路径:").grid(row=0, column=0, padx=5, pady=5)
        self.student_list_entry = tk.Entry(self.window, width=50)
        self.student_list_entry.grid(row=0, column=1, padx=5, pady=5)
        tk.Button(self.window, text="浏览", command=self.browse_student_list).grid(row=0, column=2)

        # 生成路径
        tk.Label(self.window, text="生成路径:").grid(row=1, column=0, padx=5, pady=5)
        self.output_dir_entry = tk.Entry(self.window, width=50)
        self.output_dir_entry.grid(row=1, column=1, padx=5, pady=5)
        tk.Button(self.window, text="浏览", command=self.browse_output_dir).grid(row=1, column=2)

        # 生成按钮
        tk.Button(self.window, text="生成初始文件夹", command=self.generate_folders, bg="#4CAF50", fg="white").grid(row=2, column=1, pady=10)

        # 更新根路径
        tk.Label(self.window, text="更新根路径:").grid(row=3, column=0, padx=5, pady=5)
        self.update_dir_entry = tk.Entry(self.window, width=50)
        self.update_dir_entry.grid(row=3, column=1, padx=5, pady=5)
        tk.Button(self.window, text="浏览", command=self.browse_update_dir).grid(row=3, column=2)

        # 更新按钮
        tk.Button(self.window, text="批量更新状态", command=self.batch_update_status, bg="#2196F3", fg="white").grid(row=4, column=1, pady=10)

        # 保存配置
        self.window.protocol("WM_DELETE_WINDOW", self.on_close)

    def browse_student_list(self):
        """选择学生名单文件"""
        path = filedialog.askopenfilename(filetypes=[("文本文件", "*.txt")])
        self.student_list_entry.delete(0, tk.END)
        self.student_list_entry.insert(0, path)

    def browse_output_dir(self):
        """选择生成路径"""
        path = filedialog.askdirectory()
        self.output_dir_entry.delete(0, tk.END)
        self.output_dir_entry.insert(0, path)

    def browse_update_dir(self):
        """选择更新根路径"""
        path = filedialog.askdirectory()
        self.update_dir_entry.delete(0, tk.END)
        self.update_dir_entry.insert(0, path)

    def load_config(self):
        """加载配置文件"""
        config = configparser.ConfigParser()
        if os.path.exists(self.config_file):
            config.read(self.config_file, encoding='utf-8')
            self.student_list_entry.insert(0, config.get('DEFAULT', 'student_list', fallback=''))
            self.output_dir_entry.insert(0, config.get('DEFAULT', 'output_dir', fallback=''))
            self.update_dir_entry.insert(0, config.get('DEFAULT', 'update_dir', fallback=''))

    def save_config(self):
        """保存配置文件"""
        config = configparser.ConfigParser()
        config['DEFAULT'] = {
            'student_list': self.student_list_entry.get(),
            'output_dir': self.output_dir_entry.get(),
            'update_dir': self.update_dir_entry.get()
        }
        with open(self.config_file, 'w', encoding='utf-8') as f:
            config.write(f)

    def on_close(self):
        """关闭窗口时保存配置"""
        self.save_config()
        self.window.destroy()

    def parse_student_list(self, path):
        """解析学生名单（增加退学标记识别）"""
        students = []
        try:
            with open(path, 'r', encoding='utf-8') as f:
                for line in f:
                    line = line.strip()
                    if not line:
                        continue
                    # 识别退学标记
                    is_dropout = '(已退学)' in line
                    # 清理姓名中的退学标记
                    clean_line = line.replace('(已退学)', '').strip()
                    parts = re.split(r'\s+', clean_line)
                    if len(parts) >= 2:
                        student_id = parts[0]
                        name = parts[1].strip()
                        students.append((student_id, name, is_dropout))
        except Exception as e:
            messagebox.showerror("解析错误", f"读取学生名单失败：{str(e)}")
        return students

    def generate_folders(self):
        """生成初始文件夹（增加退学学生处理）"""
        src = self.student_list_entry.get()
        dest = self.output_dir_entry.get()
        
        if not src or not dest:
            messagebox.showerror("错误", "请先选择学生名单和生成路径")
            return

        try:
            students = self.parse_student_list(src)
            total = 0
            dropout_count = 0
            for sid, name, is_dropout in students:
                # 根据退学状态生成不同后缀
                suffix = "-(已退学)" if is_dropout else "-(未提交)"
                folder_name = f"{sid}-{name}{suffix}"
                folder_path = os.path.join(dest, folder_name)
                
                if not os.path.exists(folder_path):
                    os.makedirs(folder_path)
                    total += 1
                    
                    # 为退学学生生成说明文件
                    if is_dropout:
                        dropout_count += 1
                        notice_path = os.path.join(folder_path, "此人已退学.txt")
                        with open(notice_path, 'w', encoding='utf-8') as f:
                            f.write("该学生已退学，无需提交作业。\n")
                            
            messagebox.showinfo("完成", 
                f"成功创建{total}个学生文件夹（含{dropout_count}名退学学生）")
        except Exception as e:
            messagebox.showerror("生成错误", str(e))
    
    def batch_update_status(self):
        """批量更新所有层级目录状态"""
        root_dir = self.update_dir_entry.get()
        if not root_dir:
            messagebox.showerror("错误", "请选择更新根路径")
            return

        try:
            processed = 0
            # 使用os.walk递归遍历所有目录
            for current_dir, _, _ in os.walk(root_dir):
                if self.is_student_directory(current_dir):
                    self.process_directory(current_dir)
                    processed += 1
            
            messagebox.showinfo("完成", f"已处理{processed}个作业目录")
        except Exception as e:
            messagebox.showerror("更新错误", str(e))

    def is_student_directory(self, directory):
        """判断是否是作业目录"""
        # 检查当前目录下是否有学生文件夹
        for item in os.listdir(directory):
            if self.is_student_folder(item):
                return True
        return False

    def is_student_folder(self, folder_name):
        """判断是否是学生文件夹（支持退学标记）"""
        pattern = r"^[\d\w]+-.+?(-\(未提交\)|-\(已退学\))?$"
        return re.match(pattern, folder_name) is not None

    def process_directory(self, directory):
        """处理单个作业目录（增强退学学生处理）"""
        unsubmitted = []
        total = 0
        list_path = os.path.join(directory, "未提交名单.txt")

        for folder in os.listdir(directory):
            folder_path = os.path.join(directory, folder)
            if not os.path.isdir(folder_path):
                continue

            if not self.is_student_folder(folder):
                continue

            total += 1
            
            # 检查是否是退学学生文件夹
            is_dropout = "-(已退学)" in folder
            
            # 退学学生特殊处理
            if is_dropout:
                # 确保存在说明文件
                notice_file = os.path.join(folder_path, "此人已退学.txt")
                if not os.path.exists(notice_file):
                    with open(notice_file, 'w', encoding='utf-8') as f:
                        f.write("该学生已退学，无需提交作业。\n")
                continue  # 跳过后续检查

            # 正常学生处理流程
            if any(os.listdir(folder_path)):
                if "-(未提交)" in folder:
                    new_name = folder.replace("-(未提交)", "")
                    os.rename(folder_path, os.path.join(directory, new_name))
            else:
                match = re.match(r"^[\d\w]+-(.+?)(?:-\(未提交\))?$", folder)
                if match:
                    name = match.group(1).strip()
                    unsubmitted.append(name)

        # 处理文件生成
        if total > 0:
            if unsubmitted:
                # 生成未提交名单
                parent_dir = os.path.dirname(directory)
                parent_name = os.path.basename(parent_dir)
                current_name = os.path.basename(directory)
                
                if parent_name == "" or parent_name == os.path.dirname(parent_dir):
                    header = f"<<<{current_name}>>>"
                else:
                    header = f"<<<{parent_name}-{current_name}>>>"

                content = f"{header}\n\n{' '.join(unsubmitted)}\n\n共{len(unsubmitted)}人未提交作业"
                with open(list_path, 'w', encoding='utf-8') as f:
                    f.write(content)
            else:
                # 删除未提交名单（如果存在）
                if os.path.exists(list_path):
                    os.remove(list_path)
                # 生成完成文件
                done_path = os.path.join(directory, "已全部提交完成.txt")
                with open(done_path, 'w', encoding='utf-8') as f:
                    f.write("所有学生作业已提交")


if __name__ == "__main__":
    app = HomeworkManager()
    app.window.mainloop()